#include "collision.h"
#include <iostream>





//Default Constructor
CollisionMaker::~CollisionMaker()
{
   std::cout<<"Collision Manager Shut Down!!\n";
}


CollisionMaker::CollisionMaker(irr::IrrlichtDevice* pDev)
{
   std::cout<<"Collision Manager Started Up!\n";
   mDevice = pDev;
   mSelector = mDevice->getSceneManager()->createMetaTriangleSelector();
}

irr::scene::IMetaTriangleSelector* CollisionMaker::getSelector()
{
   return mSelector;
}


irr::io::IAttributes* CollisionMaker::createUserData (irr::scene::ISceneNode *forSceneNode)
{
   //Sending 0 caus' we don't care
   return (irr::io::IAttributes*)0;
}


void CollisionMaker::OnReadUserData (irr::scene::ISceneNode *forSceneNode, irr::io::IAttributes *userData)
{
   //if the attribute is not set, it's considered false. If it's false, we don't do anything.
   if(userData->getAttributeAsBool("Collidee"))
   {
      //Detecting node type
      if(forSceneNode->getType()==irr::scene::ESNT_OCT_TREE)
      {
         //Node is an octree, let's get mesh info
         irr::io::IAttributes *attributes = mDevice->getFileSystem()->createEmptyAttributes();
         forSceneNode->serializeAttributes(attributes);
         irr::scene::IAnimatedMesh* mesh = mDevice->getSceneManager()->getMesh(attributes->getAttributeAsString("Mesh").c_str());
         attributes->drop();
         //Creating selector based on mesh
         irr::scene::ITriangleSelector* thisSelector = mDevice->getSceneManager()->createOctTreeTriangleSelector(mesh->getMesh(0), forSceneNode, 128);
         //Adding the selector to the meta selector
         mSelector->addTriangleSelector(thisSelector);
         thisSelector->drop();
      } else {
if (forSceneNode->getType() == scene::ESNT_ANIMATED_MESH)
  {
    scene::IAnimatedMeshSceneNode* msn = (scene::IAnimatedMeshSceneNode*)forSceneNode;

         irr::scene::ITriangleSelector* thisSelector =
              mDevice->getSceneManager()->createTriangleSelector(msn->getMesh()->getMesh(0), forSceneNode);
         //And we add it to the metaSelector
         mSelector->addTriangleSelector(thisSelector);
         thisSelector->drop();



      } else {

         //Node isn't an octree or animated mesh, so we build a triangle selector based on bounding box
         irr::scene::ITriangleSelector* thisSelector = mDevice->getSceneManager()->createTriangleSelectorFromBoundingBox(forSceneNode);
         //And we add it to the metaSelector
         mSelector->addTriangleSelector(thisSelector);
         thisSelector->drop();
         std::cout<< "DRAT! Bounding box!";
      }
      }
   }
   if(userData->getAttributeAsBool("Collider"))
   {
      //Now we animate nodes that are supposed to respond to collisions based on the metaselector
      //create an animator using the metaselector. Collision values are arbitrary. Elipsoid is made according to mesh bounding box
      irr::scene::ISceneNodeAnimatorCollisionResponse* anim = mDevice->getSceneManager()->createCollisionResponseAnimator(
         mSelector, forSceneNode, forSceneNode->getBoundingBox().MaxEdge,
         irr::core::vector3df(0,-1,0), irr::core::vector3df(0,0,0));
      //Adding the animator to the node
      forSceneNode->addAnimator(anim);

      anim->drop();
      std::cout<< "here at collider";
   }
}


void CollisionMaker::LoadScene(const c8 *filename)
{
   mDevice->getSceneManager()->loadScene(filename, this);
}

void CollisionMaker::AddCollisionCam ()
{
//This is my code! I adapted the collision camera code from the collision tut
//Basically I added a new function that creates a camera that collides with stuff
//to the class. I did it in the class for neatness and because all of the stuff was declared here
//any way. As to the changes to the Collision tut code i replaces smgr with
//mDevice->getSceneManager() this gets the secen manager from mDevice. Also selcector (one mesh)
//is replaced with the mSlector (definged eirler, contains sub slectors in one big slector)



	/*
	We add a first person shooter camera to the scene for being able to move in the quake 3
	level like in tutorial 2. But this, time, we add a special animator to the
	camera: A Collision Response animator. This thing modifies the scene node to which
	it is attached to in that way, that it may no more move through walls and is affected
	by gravity. The only thing we have to tell the animator is how the world looks like,
	how big the scene node is, how gravity and so on. After the collision response animator
	is attached to the camera, we do not have to do anything more for collision detection,
	anything is done automaticly, all other collision detection code below is for picking.
	And please note another cool feature: The collsion response animator can be attached
	also to all other scene nodes, not only to cameras. And it can be mixed with other
	scene node animators. In this way, collision detection and response in the Irrlicht
	engine is really, really easy.
	Now we'll take a closer look on the parameters of createCollisionResponseAnimator().
	The first parameter is the TriangleSelector, which specifies how the world, against
	collision detection is done, looks like. The second parameter is the scene node, which
	is the object, which is affected by collision detection, in our case it is the camera.
	The third defines how big the object is, it is the radius of an ellipsoid. Try it out
	and change the radius to smaller values, the camera will be able to move closer to walls
	after this. The next parameter is the direction and speed of gravity. You could
	set it to (0,0,0) to disable gravity. And the last value is just a translation: Without
	this, the ellipsoid with which collision detection is done would be around the camera,
	and the camera would be in the middle of the ellipsoid. But as human beings, we are
	used to have our eyes on top of the body, with which we collide with our world, not
	in the middle of it. So we place the scene node 50 units over the center of the
	ellipsoid with this parameter. And that's it, collision detection works now.
	*/



		scene::ICameraSceneNode* camera =
		mDevice->getSceneManager()->addCameraSceneNodeFPS(0, 100.0f, 300.0f, -1, 0, 0, true);
	camera->setPosition(core::vector3df(0,1300,0));


	if (mSelector)
	{
		scene::ISceneNodeAnimator* animcam = mDevice->getSceneManager()->createCollisionResponseAnimator(
			mSelector, camera, core::vector3df(10,50,10),
			core::vector3df(0,-0.5,0),
			core::vector3df(0,50,0));
		mSelector->drop();
		camera->addAnimator(animcam);
		animcam->drop();
	}
}

